package com.citicup.backend.webmagic;

import com.citicup.backend.dao.FundDailyMapper;
import com.citicup.backend.dao.FundInfoMapper;
import com.citicup.backend.entity.FundDaily;
import com.citicup.backend.entity.FundInfo;
import com.citicup.backend.service.FundService.FundService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;

import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class FundProcessor implements PageProcessor {

    private final Site site = Site.me().setRetryTimes(3).setSleepTime(1000);

    final FundService fundService;

    final FundInfoMapper fundInfoMapper;

    final FundDailyMapper fundDailyMapper;


    @Autowired
    public FundProcessor(FundService fundService, FundInfoMapper fundInfoMapper, FundDailyMapper fundDailyMapper) {
        this.fundService = fundService;
        this.fundInfoMapper = fundInfoMapper;
        this.fundDailyMapper = fundDailyMapper;
    }

    @Override
    public void process(Page page) {
        if (page.getUrl().toString().equals("http://fund.eastmoney.com")) {
            for(FundInfo each:fundInfoMapper.findAll()) {
                String temp = each.getFundCode();
                ArrayList<String> webs = new ArrayList<>();
                webs.add("http://fund.eastmoney.com/" + temp + ".html");
                webs.add("http://fundf10.eastmoney.com/tsdata_" + temp + ".html");
                webs.add("http://fundf10.eastmoney.com/jjjl_" + temp + ".html");
                page.addTargetRequests(webs);
            }
        } else if (page.getUrl().toString().equals("https://www.dayfund.cn/fundvalue/519056.html")) {
            for(FundInfo each:fundInfoMapper.findAll()) {
                String temp = each.getFundCode();
                page.addTargetRequest("https://www.dayfund.cn/fundvalue/" + temp + "_y.html");
            }
        } else {
            if (page.getUrl().toString().startsWith("http://fund.eastmoney.com/")) saveFund1(page);
            if (page.getUrl().toString().startsWith("http://fundf10.eastmoney.com/tsdata_")) saveFund2(page);
            if (page.getUrl().toString().startsWith("http://fundf10.eastmoney.com/jjjl_")) saveFund3(page);
            if (page.getUrl().toString().startsWith("https://www.dayfund.cn/fundvalue/")) saveHistory(page);
        }
    }


    //获取界面一的fundInfo和fundDaily，将fundDaily传给pipeline
    private void saveFund1(Page page) {
        Html html = page.getHtml();

        //基金经理
        String manager = html.xpath("//*[@class='infoOfFund']/table/tbody/tr[1]/td[3]/a/text()").toString();
        //基金规模
        String scale_string = html.xpath("//*[@class='infoOfFund']/table/tbody/tr[1]/td[2]/text()").toString().substring(1, 5);
        double scale = Double.parseDouble(scale_string);
        //基金建立日期
        String fund_date = html.xpath("//*[@class='infoOfFund']/table/tbody/tr[2]/td[1]/text()").toString().substring(3, 11);
        //今天的日期
        String date_string = html.xpath("//*[@class='dataItem02']//p/text()").toString().substring(2, 10);
        //基金代码
        String fundCode = html.xpath(("//*[@class='ui-num']/text()")).toString();
        //基金名字
        String fund_name = html.xpath("//*[@class='fundDetail-tit']/div/text()").toString();

        String[] fucking_data = new String[10];
        //单位净值
        fucking_data[0] = html.xpath("//*[@class='dataOfFund']/dl[2]/dd[1]/span[1]/text()").toString();
        //累计净值
        fucking_data[1] = html.xpath("//*[@class='dataOfFund']/dl[3]/dd[1]/span/text()").toString();
        //近1月
        fucking_data[2] = html.xpath("//*[@class='dataOfFund']/dl[1]/dd[2]/span[2]/text()").toString();
        //近3月
        fucking_data[3] = html.xpath("//*[@class='dataOfFund']/dl[2]/dd[2]/span[2]/text()").toString();
        //近6月
        fucking_data[4] = html.xpath("//*[@class='dataOfFund']/dl[3]/dd[2]/span[2]/text()").toString();
        //近1年
        fucking_data[5] = html.xpath("//*[@class='dataOfFund']/dl[1]/dd[3]/span[2]/text()").toString();
        //近3年
        fucking_data[6] = html.xpath("//*[@class='dataOfFund']/dl[2]/dd[3]/span[2]/text()").toString();
        //成立以来
        fucking_data[7] = html.xpath("//*[@class='dataOfFund']/dl[3]/dd[3]/span[2]/text()").toString();
        //近1日
        fucking_data[8] = html.xpath("//*[@class='dataOfFund']/dl[2]/dd[1]/span[2]/text()").toString();
        //近1周
        fucking_data[9] = html.xpath("//*[@class='increaseAmount']/table/tbody/tr[2]/td[2]/div/text()").toString();

        for (int i = 2; i <= 9; i++) {
            fucking_data[i] = fucking_data[i].substring(0, fucking_data[i].length() - 1);
        }

        FundDaily fundDaily = new FundDaily();
        fundDaily.setValue(Double.parseDouble(fucking_data[0]));
        fundDaily.setAcValue(Double.parseDouble(fucking_data[1]));
        fundDaily.setMonthRate(Double.parseDouble(fucking_data[2]));
        fundDaily.setThreeMonthsRate(Double.parseDouble(fucking_data[3]));
        fundDaily.setSixMonthsRate(Double.parseDouble(fucking_data[4]));
        fundDaily.setYearRate(Double.parseDouble(fucking_data[5]));
        fundDaily.setThreeYearsRate(Double.parseDouble(fucking_data[6]));
        fundDaily.setAllRate(Double.parseDouble(fucking_data[7]));
        fundDaily.setDayRate(Double.parseDouble(fucking_data[8]));
        fundDaily.setWeekRate(Double.parseDouble(fucking_data[9]));
        fundDaily.setDate(date_string);
        fundDaily.setFundCode(fundCode);


        FundInfo fundInfo;
        fundInfo = new FundInfo();


        fundInfo.setFundScale(scale);
        fundInfo.setDate(date_string);
        fundInfo.setFoundDate(fund_date);
        fundInfo.setFundCode(fundCode);
        fundInfo.setManager(manager);
        fundInfo.setFundName(fund_name);
        fundInfo.setYearInterestsRate(Double.parseDouble(fucking_data[5]));

        List<FundDaily> pastDaily = fundDailyMapper.findByFundCodeAndDate(fundCode, date_string);
        if (pastDaily.size() == 0)
            page.putField("FundDaily", fundDaily);

        page.putField("FundInfo", fundInfo);
    }


    //获得界面二的fundInfo
    private void saveFund2(Page page) {
        Html html = page.getHtml();
        String bodong = html.xpath("//*[@class='fxtb']/tbody/tr[2]/td[2]/text()").toString();
        bodong = bodong.substring(0, bodong.length() - 1);
        String xapu = html.xpath("//*[@class='fxtb']/tbody/tr[3]/td[2]/text()").toString();
        String info = html.xpath("//*[@class='fxtb']/tbody/tr[4]/td[2]/text()").toString();

        FundInfo fundInfo = new FundInfo();

        if (info != null) {
            double infoRate = Double.parseDouble(info);
            fundInfo.setInfoRate(infoRate);
        }
        double fluc = Double.parseDouble(bodong);
        double xa = Double.parseDouble(xapu);
        fundInfo.setYearFlucRate(fluc);
        fundInfo.setXpRate(xa);
        fundInfo.setFundCode(page.getUrl().toString().substring(36, 42));
        page.putField("FundInfo", fundInfo);
    }

    //获得界面三的funInfo,并将fundInfo数据提交给pipeline
    private void saveFund3(Page page) {
        Html html = page.getHtml();
        String managerYear = html.xpath("//*[@class='w782 comm  jloff']/tbody/tr[1]/td[4]/text()").toString();
        int date = calculate(managerYear);
        FundInfo fundInfo = new FundInfo();
        fundInfo.setManagerYear(date);
        fundInfo.setFundCode(page.getUrl().toString().substring(34, 40));

        page.putField("FundInfo", fundInfo);
    }

    private static int calculate(String year) {
        char[] c = year.toCharArray();
        int index1 = 0;
        int index2 = 0;
        for (int i = 0; i < year.length(); i++) {
            if (c[i] == '年') {
                index1 = i;
            }
            if (c[i] == '天') {
                index2 = i;
            }
        }
        if (index1 != 0) {
            String years = year.substring(0, index1);
            String days = year.substring(index1 + 2, index2);
            int x = Integer.parseInt(years);
            int y = Integer.parseInt(days);
            System.out.print(x * 365 + y);
            return x * 365 + y;
        } else {
            String days = year.substring(0, index2);
            return Integer.parseInt(days);
        }
    }

    private void saveHistory(Page page) {
        Html html = page.getHtml();
        String fundCode = page.getUrl().toString().substring(33, 39);
        List<FundDaily> fundDailies = new ArrayList<>();
        for (int i = 3; i < 300; i++) {
            if (i == 12 || i == 28)
                continue;
            String date = html.xpath("//table[@class='mt1 clear']/tbody/tr[" + i + "]/td[1]/text()").toString();
            if (date == null) {
                System.err.println("null");
                break;
            } else
                date = date.substring(2);
            double value = Double.parseDouble(html.xpath("//table[@class='mt1 clear']/tbody/tr[" + i + "]/td[4]/text()").toString());
            FundDaily fundDaily = new FundDaily();
            fundDaily.setFundCode(fundCode);
            fundDaily.setDate(date);
            fundDaily.setValue(value);
            //System.err.println(date + " " + value);
            List<FundDaily> pastDaily = fundDailyMapper.findByFundCodeAndDate(fundCode, date);
            if (pastDaily.size() == 0) {
                fundDailies.add(fundDaily);
            }
        }
        page.putField("historyFund", fundDailies);
    }

    @Override
    public Site getSite() {
        return site;
    }

}
